package com.liang.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liang.mapper.UserandnoticeDAO;
import com.liang.pojo.dto.NoticeDto;
import com.liang.myWebSocketServer.WebSocketServer;
import com.liang.pojo.Notice;

import java.util.*;
import java.util.stream.Collectors;

import com.liang.mapper.NoticeDAO;
import javax.annotation.Resource;

import com.liang.pojo.userandnotice;
import com.liang.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.liang.service.NoticeService;
import org.springframework.transaction.annotation.Transactional;

/**
 *@作者:lsk
 *Service实现类
 *@Date:2023/10/16
*/
@Service
public class NoticeServiceImpl  implements NoticeService{


	@Resource
	private NoticeDAO noticedao;

	@Value("notice")
	private String noticeTitle;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@Autowired
	WebSocketServer webSocketServer;

	@Resource
	UserandnoticeDAO userandnoticeDAO;



	/**
	 * 根据Noticeid查询
	 */
	public Object selectByNoticeid(Long noticeid) {
		return noticedao.selectByNoticeid(noticeid);
	}


	/**
	 * 根据Noticeid更新
	 */
	public Integer updateByNoticeid(Notice demo) {
		return noticedao.updateByNoticeid(demo);
	}


	/**
	 * 根据Noticeid删除
	 */
	public Integer deleteByNoticeid(Long noticeid) {
		return noticedao.deleteByNoticeid(noticeid);
	}


	/**
	 * insert:(插入)
	 */
	public Object insert(Notice demo) {
		noticedao.insertlsk(demo);
		return demo;
	}


	/**
	 * insertOrUpdate(插入或更新(根据主键或唯一索引更新，主键和唯一索引不会改变))
	 */
	public Integer insertOrUpdate(Notice demo) {
		return noticedao.insertOrUpdatelsk(demo);
	}


	/**
	 * insertBath:(批量插入)
	 */
	public Integer insertBatch(List<Notice> list) {
		return noticedao.insertBatchlsk(list);
	}


	/**
	 * insertOrUpdateBatch:(批量插入或更新)
	 */
	public Integer insertOrUpdateBatch(List<Notice> list) {
		return noticedao.insertOrUpdateBatchlsk(list);
	}


	/**
	 * selectList:(根据参数查询集合)
	 */
	public List<Notice> selectList(Map<String, Object> param) {
		if (param.get("pageNum") != null) {
			int start = Integer.parseInt(param.get("pageSize").toString()) * (Integer.parseInt(param.get("pageNum").toString()) - 1);
			param.put("pageNum", start);
		}
		return noticedao.selectListlsk(param);
	}


	/**
	 * selectCount:(根据集合查询数量)
	 */
	public Long selectCount(Map<String, Object> param) {
		return noticedao.selectCountlsk(param);
	}


	/**
	 * 插入信息到数据库中，publish_time，create_time，update_time 赋值
	 *
	 * @param notice
	 * @return
	 */
	@Override
	public Boolean NoticePublish(Notice notice) {

		//获取当前时间字符串
		String todayDateTime = DateUtils.getTodayDateTime();

		notice.setCreate_time(todayDateTime);

		notice.setPublish_time(todayDateTime);

		notice.setUpdate_time(todayDateTime);
		Integer insert = noticedao.insertlsk(notice);

		return insert > 0 ? true : false;
	}

	/**
	 * 分页查找noticeDto的信息用于用户查询notice信息
	 *
	 * @param noticeDto
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public PageInfo<NoticeDto> getNoticesAndPage(NoticeDto noticeDto) {

		//开启分页插件
		PageHelper.startPage(noticeDto.getPageNum(), noticeDto.getPageSize());

		//计算分页条件
		Integer start = (noticeDto.getPageNum() - 1) * noticeDto.getPageSize();
		Integer limit = noticeDto.getPageSize();
		noticeDto.setStart(start);
		noticeDto.setLimit(limit);

		List<NoticeDto> noticeDtoList = noticedao.getNoticeDtos(noticeDto);
		PageInfo<NoticeDto> pageInfo = new PageInfo<>(noticeDtoList);

		//查询总记录数量设置给pageinfo对象
		Integer count = noticedao.getNoticeDtoCount(noticeDto.getUser_id());
		pageInfo.setTotal(count);
		return pageInfo;
	}

	/**
	 * 获取本单位的发布历史
	 * @param noticeDto
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public PageInfo<NoticeDto> getNoticesHistory(NoticeDto noticeDto) {

		//开启分页插件
		PageHelper.startPage(noticeDto.getPageNum(), noticeDto.getPageSize());

		//计算分页条件
		Integer start = (noticeDto.getPageNum() - 1) * noticeDto.getPageSize();
		Integer limit = noticeDto.getPageSize();
		noticeDto.setStart(start);
		noticeDto.setLimit(limit);

		//获取当前用户发布的通告列表
		List<NoticeDto> noticeDtoList = noticedao.getNoticesHistory(noticeDto);

		//获取记录总条数，用于前端分页使用
		Integer total = noticedao.getNoticesHistoryCounts(noticeDto);



		//设置每条记录的获取人数,和为未获取人数（从redis中获取）
		List<NoticeDto> collect = noticeDtoList.stream().map((item) -> {
			//设置该通知接受了的人数
			Long notice_id = item.getNotice_id();
			Integer num = noticedao.getNoticeReceiveNum(notice_id);
			item.setReceiveNum(num);
			//redis中获取未接受人数
			Long size = redisTemplate.opsForSet().size(noticeTitle + notice_id);
			item.setUnreceiveNum(size.intValue());
			return item;
		}).collect(Collectors.toList());

		//构造分页对象
		PageInfo<NoticeDto> info = new PageInfo<>(collect);
		info.setTotal(total);
		return info;
	}

	/**
	 * 发送消息给未接受的用户信息，利用websocket发送及时消息
	 * @param noticeId
	 * @return
	 */
	@Override
	public Boolean publishNotice(Long noticeId) {

		//获取redis中应该接受该notice的用户的user列表。
		Set<String> userids = redisTemplate.opsForSet().members(noticeTitle + noticeId);

		//获取notice消息
		Notice notice = noticedao.selectByNoticeid(noticeId);

		//获取通知题目告知用户是那个通知
		String titile = notice.getTitile();

		//将set中的string转化为long类型，并且调用socket的接口，发送单体消息。
		userids.stream().forEach((item)->{
			long userid = Long.parseLong(item);
			webSocketServer.sendOneMessage(userid,"请尽快接受标题为"+titile+"的通知!!!");
		});
		return true;
	}

	/**
	 * 查看上级通知
	 * @param noticeDto
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public PageInfo<NoticeDto> getSuperiorNotice(NoticeDto noticeDto) {

		//获取当前用户的userid
		Long user_id = noticeDto.getUser_id();

		//开启分页插件
		PageHelper.startPage(noticeDto.getPageNum(), noticeDto.getPageSize());

		//计算分页条件
		Integer start = (noticeDto.getPageNum() - 1) * noticeDto.getPageSize();
		Integer limit = noticeDto.getPageSize();
		noticeDto.setStart(start);
		noticeDto.setLimit(limit);

		//获取上级通知列表
		List<NoticeDto> noticeDtoList = noticedao.getSuperiorNotice(noticeDto);

		if(noticeDtoList.size() != 0){	//设置每个中的 notice_status；
			noticeDtoList.stream().forEach((item)->{
			  userandnotice userandnotice =	userandnoticeDAO.select(user_id,item.getNotice_id());
				item.setNotice_status(userandnotice.getNotice_status());
			});
		}

		//查询总记录数
		Integer total = noticedao.getSuperiorNoticeCount(noticeDto);

		//构造分页对象
		PageInfo<NoticeDto> info = new PageInfo<>(noticeDtoList);
		info.setTotal(total);

		return info;
	}
}